package de.hs_mannheim.vem.ajchat.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SpringLayout;
import com.oracle.SpringUtilities;
import de.hs_mannheim.vem.ajchat.TcpConnection;

public final class SockSelect extends JPanel {
	public interface ResultReceiver {
		void receiveResult(SocketAddress insa);
	}

	private static final long	serialVersionUID	= 1597013183209930039L;

	public static SocketAddress selectSocket(final String title, final JFrame parent, final boolean freeSelect)
			throws SocketException {
		final JDialog jd = new JDialog(parent, title);
		final BorderLayout lay = new BorderLayout();
		lay.setHgap(5);
		lay.setVgap(5);
		jd.setLayout(lay);
		final SockSelect ss = new SockSelect(freeSelect);
		final JButton select = new JButton("Select");

		jd.add(ss, BorderLayout.CENTER);
		jd.add(select, BorderLayout.SOUTH);
		jd.pack();
		jd.setResizable(false);
		jd.setVisible(true);

		final Object mutex = new Object();

		select.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent arg0) {
				synchronized (mutex) {
					mutex.notify();
					jd.setVisible(false);
				}
			}
		});

		boolean keepWaiting = true;
		do {
			try {
				synchronized (mutex) {
					mutex.wait();
				}
				keepWaiting = false;
			} catch (final InterruptedException e) {
				e.printStackTrace();
			}
		} while (keepWaiting);
		jd.setVisible(false);
		return ss.getValue();
	}

	public static void selectSocketAsync(final String title, final JFrame parent, final boolean freeSelect,
			final ResultReceiver receiver) {
		Executors.defaultThreadFactory().newThread(new Runnable() {
			@Override
			public void run() {
				try {
					receiver.receiveResult(selectSocket(title, parent, freeSelect));
				} catch (final SocketException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}).start();
	}

	private final JComboBox		ipSelect;
	private final JTextField	ipEdit;
	private final JSpinner		portSpinner	= new JSpinner();

	public SockSelect(final boolean freeSelect) throws SocketException {
		super(new SpringLayout());
		if (freeSelect) {
			add(new JLabel("IP/Hostname"));
			ipEdit = new JTextField("127.0.0.1");
			ipSelect = null;
			add(ipEdit);
		} else {
			add(new JLabel("IP"));
			ipSelect = new JComboBox(TcpConnection.getIPs());
			ipEdit = null;
			add(ipSelect);
		}

		portSpinner.setModel(new SpinnerNumberModel(5678, 1024, Short.MAX_VALUE, 1));

		add(new JLabel("Port"));
		add(portSpinner);

		SpringUtilities.makeCompactGrid(this, 2, 2, // rows, cols
				5, 5, // initialX, initialY
				10, 5);// xPad, yPad);
	}

	public SocketAddress getValue() {
		try {
			return new InetSocketAddress((ipSelect == null ? InetAddress.getByName(ipEdit.getText())
					: (InetAddress) ipSelect.getSelectedItem()), (Integer) portSpinner.getValue());
		} catch (final UnknownHostException e) {
			return null;
		}
	}
}
